package com.example.myapplication2003;

import java.util.*;

//计算 2*(4+(88-86)/2)


//计算 2*(4+(88-86)/2)

class Caculater {
    private String[] sArry;//存分割后的字符串
    private Stack<String> houx = new Stack<String>();
    private Stack<String> fuhao = new Stack<String>();

    //结构初始化
    Caculater(String str) {
        int i = str.length() - 1;
        String temp = "";
        int j = 0;
        Boolean bool = true;
        //在符号左右各添加一个#字符划分
        while (true) {
            if (!bool) break;
            if (i == j) {
                bool = false;
            }
            if (str.charAt(j) == '+'
                    || str.charAt(j) == '-'
                    || str.charAt(j) == '*'
                    || str.charAt(j) == '/'
                    || str.charAt(j) == '('
                    || str.charAt(j) == ')') {
                temp += '#';
                temp += str.charAt(j);
                temp += '#'; //填完后是2#*##(#4#+##(#88#-#86#)##/#32#)#
            } else {
                temp += str.charAt(j);
            }
            j++;
        }
        sArry = temp.split("#+");//用正则表达式分割成字符串，#+表示一个或多个#字符//结果：[2,*,(,4,+,(,88,-,85,),/,2,)]
    }

    //后序排列
    public void backsort() {
        //循环sArry
        for (int i = 0; i < sArry.length; i++) {
            //如果不是字符，就直接push入houx栈
            if (!sArry[i].equals("+")
                    && !sArry[i].equals("-")
                    && !sArry[i].equals("*")
                    && !sArry[i].equals("/")
                    && !sArry[i].equals("(")
                    && !sArry[i].equals(")")) {
                houx.push(sArry[i]);
                continue;
                //否则是字符，若符号栈为空，直接入栈
            } else if (fuhao.isEmpty()) {
                fuhao.push(sArry[i]);
                continue;
                //如果为（括号，直接入符号栈
            } else if (sArry[i].equals("(")) {
                fuhao.push(sArry[i]);
                continue;
                //如果为）括号
            } else if (sArry[i].equals(")")) {
                /**
                 * 不断出栈直到（括号出现
                 *
                 */
                while (!fuhao.peek().equals("(")) {
                    houx.push(fuhao.pop());
                }
                fuhao.pop();//清掉（括号
                //如果不为空，且要入的符号比符号栈顶的符号优先级高，则直接push入符号栈
            } else if (!fuhao.isEmpty() && check(sArry[i], fuhao.peek())) { //
                fuhao.push(sArry[i]);
                continue;
                //否则，将符号栈内优先级高的符号出栈，push入houx栈，再将符号存进符号栈
            } else {
                houx.push(fuhao.pop());
                fuhao.push(sArry[i]);
                continue;
            }
        }
        //遍历完后，直接将符号栈内的依次出栈，push入houx栈
        while (!fuhao.isEmpty()) {
            houx.push(fuhao.pop());
        }//结果是：2 4 88 86 - 2 / + * 栈内顺序
    }

    //check对比优先级
    private boolean check(String a, String b) {
        //如果符号栈内是（括号，直接返true
        if (b.equals("(")) {
            return true;
        }
        //如果符号栈内的优先级比要入的高，返回false
        if ((b.equals("*") || b.equals("/")) && (a.equals("+") || a.equals("-"))) { //b>a
            return false;
        }
        //。。。。。。。。。。。。。的低，返回true
        if ((b.equals("+") || b.equals("-")) && (a.equals("*") || a.equals("/"))) { //b<a
            return true;
        }
        return false;
    }

    //出栈计算
    public Double suan() {

        backsort();//后序排列

        //结果栈end
        Stack<Double> end = new Stack<Double>();
        //遍历houx栈
        for (int i = 0; i < houx.size(); i++) {
            //如果是加号，end pop出来两个数字，计算后结果入栈
            if (houx.get(i).equals("+")) {
                Double b = end.pop();
                Double a = end.pop();
                end.push(a + b);
                continue;
                //如果是减号，end pop出栈两个数字，计算后结果入栈
            } else if (houx.get(i).equals("-")) {
                Double b = end.pop();
                Double a = end.pop();
                end.push(a - b);
                continue;
                //如果是乘号，end pop出栈两个数字，计算后结果入栈
            } else if (houx.get(i).equals("*")) {
                Double b = end.pop();
                Double a = end.pop();
                end.push(a * b);
                continue;
                //如果是除号，end pop出栈两个数字，计算后结果入栈
            } else if (houx.get(i).equals("/")) {
                Double b = end.pop();
                Double a = end.pop();
                end.push(a / b);
                continue;
            } else if (houx.get(i).isEmpty()) {

                continue;
            } else {
                //不是符号，也就是数字的情况，Integer.parseInt转int型， push入栈
                end.push(Double.parseDouble(houx.get(i)));
            }

        }

        //输出结果
        return end.pop();
    }

}

public class Calculator {
    static String str="";
    public Double Eval(String str){
        //结构化
        Caculater cl = new Caculater(str);
        //计算
        Double result = cl.suan();
        return result;
    }
}